package com.itheima.tanhua.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.tanhua.Dto.PageResult;
import com.itheima.tanhua.entity.User;
import com.itheima.tanhua.entity.UserInfo;
import com.itheima.tanhua.entity.UserLocation;
import com.itheima.tanhua.mapper.UserMapper;
import com.itheima.tanhua.mapper.UsersMapper;
import com.itheima.tanhua.service.UserService;
import com.itheima.tanhua.vo.UserInfoVo;
import com.itheima.tanhua.vo.UserPageVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.mongo.MongoClientDependsOnBeanFactoryPostProcessor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author maorf
 * @version 1.0
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserInfo> implements UserService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public PageResult list(Integer page, Integer pagesize, Long id, String nickname, String city) {
        Page<UserInfo> page1 = new Page<>(page, pagesize);
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(!ObjectUtils.isEmpty(id),UserInfo::getId,id);
        wrapper.like(!ObjectUtils.isEmpty(nickname),UserInfo::getNickname,nickname);
        wrapper.like(!ObjectUtils.isEmpty(city),UserInfo::getCity,city);
        page(page1,wrapper);
        List<UserInfo> records = page1.getRecords();
        if (ObjectUtils.isEmpty(records)) {
            return new PageResult(page, pagesize, Math.toIntExact(page1.getTotal()), null);
        }
        List<UserPageVo> list =new ArrayList<>();
        for (UserInfo record : records) {
            UserPageVo userInfoVo = new UserPageVo();
            userInfoVo.setId(Math.toIntExact(record.getId()));
            userInfoVo.setNickname(record.getNickname());
            User user = usersMapper.selectById(record.getId());
            userInfoVo.setMobile(user.getMobile());
            userInfoVo.setSex(record.getGender().equals("man")?"男":"女");
            userInfoVo.setAge(record.getAge());
            userInfoVo.setIncome(Integer.valueOf(record.getIncome()) * 100);
            userInfoVo.setOccupation(record.getProfession());
            userInfoVo.setUserStatus(findUserStatus(record.getId()));
            userInfoVo.setCreated(record.getCreated().getTime());
            userInfoVo.setCity(record.getCity());
            userInfoVo.setLastActiveTime(findLastActiveTime(record.getId()));
            userInfoVo.setLogo(record.getAvatar());
            list.add(userInfoVo);
        }
        return new PageResult(page,pagesize, (int) page1.getTotal(),list);

    }

    @Override
    public UserInfoVo findById(Long userID) {
        UserInfo userInfo = this.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getId, userID));
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setId(Math.toIntExact(userInfo.getId()));
        userInfoVo.setNickname(userInfo.getNickname());
        User user = usersMapper.selectById(userInfo.getId());
        userInfoVo.setMobile(user.getMobile());
        userInfoVo.setSex(userInfo.getGender().equals("man")?"男":"女");
        userInfoVo.setAge(userInfo.getAge());
        userInfoVo.setIncome(Integer.valueOf(userInfo.getIncome()) * 100);
        userInfoVo.setOccupation(userInfo.getProfession());
        userInfoVo.setUserStatus(findUserStatus(userInfo.getId()));
        userInfoVo.setCreated(userInfo.getCreated().getTime());
        userInfoVo.setCity(userInfo.getCity());
        userInfoVo.setLastActiveTime(findLastActiveTime(userInfo.getId()));
        userInfoVo.setLogo(userInfo.getAvatar());
        userInfoVo.setTags(userInfo.getTags());
        userInfoVo.setPersonalSignature("天天开心");
        userInfoVo.setCountLiked(findCountLikedById(userID));
        userInfoVo.setCountBeLiked(findCountBeLikedById(userID));
        userInfoVo.setCountMatching(findCountMatching(userID));
        userInfoVo.setLastLoginLocation(findLastLoginLocation(userID));
        return userInfoVo;


    }

    public Integer findCountBeLikedById(Long userId) {
        Query query = Query.query(Criteria.where("likeUserId").is(userId));
        long count = mongoTemplate.count(query, "user_like");
        return Math.toIntExact(count);
    }

    public Integer findCountLikedById(Long userId) {
        Query query = Query.query(Criteria.where("userId").is(userId));
        long count = mongoTemplate.count(query, "user_like");
        return Math.toIntExact(count);
    }

    public Integer findCountMatching(Long userId) {
        Query query = Query.query(Criteria.where("userId").is(userId));
        long count = mongoTemplate.count(query, "friend");
        return Math.toIntExact(count);
    }

    public String findUserStatus(Long userId) {
        Object freezingRange = redisTemplate.opsForHash().get("freeze_" + userId, "freezingRange");
        if (ObjectUtils.isEmpty(freezingRange)) {
            return "1";
        } else {
            return "2";
        }
    }

    public Long findLastActiveTime(Long userId) {
        Query query = Query.query(Criteria.where("userId").is(userId));
        UserLocation userLocations = mongoTemplate.findOne(query, UserLocation.class);
        if (ObjectUtils.isEmpty(userLocations)) {
            return Long.valueOf(-1);
        } else {
            return (userLocations.getLastUpdated());
        }
    }

    public String findLastLoginLocation(Long userId) {
        Query query = Query.query(Criteria.where("userId").is(userId));
        UserLocation userLocations = mongoTemplate.findOne(query, UserLocation.class);
        if (ObjectUtils.isEmpty(userLocations)) {
            return "";
        } else {
            return (userLocations.getAddress());
        }
    }
}
